/**============================================================================
 Confidential Information - Limited distribution to authorized persons only.
 This software is protected as an unpublished work under the U.S. Copyright
 Act of 1976.

 Copyright (c) 2012, BluePhoenix Solutions, Inc. All rights reserved.
 ----------------------------------------------------------------------------
 file......: UtilsTest.java
 Author....: Vyacheslav Kovalyov
 Created...: 2/16/12

 Description:

 ============================================================================*/
package ru.monyag.android.vibralarm.utils;

import org.junit.Test;
import ru.monyag.android.vibralarm.alarm.DayOfWeek;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import static java.util.Arrays.asList;
import static org.apache.commons.lang.StringUtils.EMPTY;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static ru.monyag.android.vibralarm.alarm.DayOfWeek.*;
import static ru.monyag.android.vibralarm.utils.Utils.makeDaysString;
import static ru.monyag.android.vibralarm.utils.Utils.parseDaysString;

/**
 * @author Vyacheslav Kovalyov
 * @version 1.0
 */
public class UtilsTest {

    //makeDaysString tests
    private static final List<DayOfWeek> EVERYDAY_1 = asList(EVERY_DAY);
    private static final List<DayOfWeek> EVERYDAY_2 = asList(WEEKDAYS, WEEKENDS);
    private static final List<DayOfWeek> EVERYDAY_3 = asList(WEEKDAYS, SUNDAY, SATURDAY);
    private static final List<DayOfWeek> EVERYDAY_4 = asList(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, WEEKENDS);
    private static final List<DayOfWeek> EVERYDAY_5 = asList(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SUNDAY, SATURDAY);
    private static final List<DayOfWeek> EVERYDAY_6 = asList(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, EVERY_DAY, FRIDAY, WEEKDAYS, WEEKENDS, WEEKDAYS, SUNDAY, SATURDAY, SUNDAY, SATURDAY);
    private static final List<DayOfWeek> EVERYDAY_7 = asList(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, WEEKDAYS, WEEKDAYS, SUNDAY, SATURDAY, SUNDAY, SATURDAY);
    private static final List<DayOfWeek> EVERYDAY_8 = asList(SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY);

    private static final List<DayOfWeek> WEEKENDS_1 = asList(WEEKENDS);
    private static final List<DayOfWeek> WEEKENDS_2 = asList(SUNDAY, SATURDAY);
    private static final List<DayOfWeek> WEEKENDS_3 = asList(SUNDAY, WEEKENDS);
    private static final List<DayOfWeek> WEEKENDS_4 = asList(WEEKENDS, SATURDAY);
    private static final List<DayOfWeek> WEEKENDS_5 = asList(SUNDAY, SATURDAY, WEEKENDS, SATURDAY);

    private static final List<DayOfWeek> WEEKDAYS_1 = asList(WEEKDAYS);
    private static final List<DayOfWeek> WEEKDAYS_2 = asList(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY);
    private static final List<DayOfWeek> WEEKDAYS_3 = asList(WEEKDAYS, MONDAY, TUESDAY, FRIDAY);
    private static final List<DayOfWeek> WEEKDAYS_4 = asList(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, WEEKDAYS);

    private static final List<DayOfWeek> DAYS_1 = asList(SUNDAY, MONDAY);
    private static final List<DayOfWeek> DAYS_2 = asList(WEEKDAYS, SUNDAY);
    private static final List<DayOfWeek> DAYS_3 = asList(WEEKENDS, MONDAY);
    private static final List<DayOfWeek> DAYS_4 = asList(WEEKENDS, MONDAY, SUNDAY, THURSDAY);
    private static final List<DayOfWeek> DAYS_5 = asList(WEEKENDS, MONDAY, MONDAY, MONDAY, MONDAY, MONDAY, MONDAY);

    @Test
    public void shouldReturnDaysListString() throws Exception {
        assertThat(makeDaysString(DAYS_1).length() == "SUNDAY,MONDAY".length(), is(true));
        assertThat(makeDaysString(DAYS_2).length() == "WEEKDAYS,SUNDAY".length(), is(true));
        assertThat(makeDaysString(DAYS_3).length() == "WEEKENDS,MONDAY".length(), is(true));
        assertThat(makeDaysString(DAYS_4).length() == "WEEKENDS,MONDAY,THURSDAY".length(), is(true));
        assertThat(makeDaysString(DAYS_5).length() == "WEEKENDS,MONDAY".length(), is(true));
    }

    @Test
    public void shouldReturnEverydayString() throws Exception {
        assertThat(makeDaysString(EVERYDAY_1).equals(EVERY_DAY.name()), is(true));
        assertThat(makeDaysString(EVERYDAY_2).equals(EVERY_DAY.name()), is(true));
        assertThat(makeDaysString(EVERYDAY_3).equals(EVERY_DAY.name()), is(true));
        assertThat(makeDaysString(EVERYDAY_4).equals(EVERY_DAY.name()), is(true));
        assertThat(makeDaysString(EVERYDAY_5).equals(EVERY_DAY.name()), is(true));
        assertThat(makeDaysString(EVERYDAY_6).equals(EVERY_DAY.name()), is(true));
        assertThat(makeDaysString(EVERYDAY_7).equals(EVERY_DAY.name()), is(true));
        assertThat(makeDaysString(EVERYDAY_8).equals(EVERY_DAY.name()), is(true));
    }

    @Test
    public void shouldReturnWeekdaysString() throws Exception {
        assertThat(makeDaysString(WEEKDAYS_1).equals(WEEKDAYS.name()), is(true));
        assertThat(makeDaysString(WEEKDAYS_2).equals(WEEKDAYS.name()), is(true));
        assertThat(makeDaysString(WEEKDAYS_3).equals(WEEKDAYS.name()), is(true));
        assertThat(makeDaysString(WEEKDAYS_4).equals(WEEKDAYS.name()), is(true));
    }

    @Test
    public void shouldReturnWeekendsString() throws Exception {
        assertThat(makeDaysString(WEEKENDS_1).equals(WEEKENDS.name()), is(true));
        assertThat(makeDaysString(WEEKENDS_2).equals(WEEKENDS.name()), is(true));
        assertThat(makeDaysString(WEEKENDS_3).equals(WEEKENDS.name()), is(true));
        assertThat(makeDaysString(WEEKENDS_4).equals(WEEKENDS.name()), is(true));
        assertThat(makeDaysString(WEEKENDS_5).equals(WEEKENDS.name()), is(true));
    }

    @Test
    public void shouldReturnEmptyString() throws Exception {
        assertThat(makeDaysString(Collections.EMPTY_LIST).equals(EMPTY), is(true));
    }

    //parseDaysString tests
    private static final String STRING_EVERYDAY_1 = "EVERY_DAY";
    private static final String STRING_EVERYDAY_2 = "WEEKDAYS, WEEKENDS";
    private static final String STRING_EVERYDAY_3 = "WEEKDAYS, SUNDAY, SATURDAY";
    private static final String STRING_EVERYDAY_4 = "MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, WEEKENDS";
    private static final String STRING_EVERYDAY_5 = "MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SUNDAY, SATURDAY";
    private static final String STRING_EVERYDAY_6 = "MONDAY, TUESDAY, WEDNESDAY, THURSDAY, EVERY_DAY, FRIDAY, WEEKDAYS, WEEKENDS, WEEKDAYS, SUNDAY, SATURDAY, SUNDAY, SATURDAY";
    private static final String STRING_EVERYDAY_7 = "MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, WEEKDAYS, WEEKDAYS, SUNDAY, SATURDAY, SUNDAY, SATURDAY";
    private static final String STRING_EVERYDAY_8 = "SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY";

    private static final String STRING_WEEKENDS_1 = "WEEKENDS";
    private static final String STRING_WEEKENDS_2 = "SUNDAY, SATURDAY";
    private static final String STRING_WEEKENDS_3 = "SUNDAY, WEEKENDS";
    private static final String STRING_WEEKENDS_4 = "WEEKENDS, SATURDAY";
    private static final String STRING_WEEKENDS_5 = "SUNDAY, SATURDAY, WEEKENDS, SATURDAY";

    private static final String STRING_WEEKDAYS_1 = "WEEKDAYS";
    private static final String STRING_WEEKDAYS_2 = "MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY";
    private static final String STRING_WEEKDAYS_3 = "WEEKDAYS, MONDAY, TUESDAY, FRIDAY";
    private static final String STRING_WEEKDAYS_4 = "MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, WEEKDAYS";

    private static final String STRING_DAYS_1 = "SUNDAY, MONDAY";
    private static final String STRING_DAYS_2 = "WEEKDAYS, SUNDAY";
    private static final String STRING_DAYS_3 = "WEEKENDS, MONDAY";
    private static final String STRING_DAYS_4 = "WEEKENDS, MONDAY, SUNDAY, THURSDAY";
    private static final String STRING_DAYS_5 = "WEEKENDS, MONDAY, MONDAY, MONDAY, MONDAY, MONDAY, MONDAY";

    private static final String INVALID_STRING = ",,,       Sosiski!!!!                       ,, ,, , , ,,,,,,,,,,";

    @Test
    public void shouldReturnEveryday() throws Exception {

        List<DayOfWeek> everyDays = asList(EVERY_DAY);

        assertThat(isEquals(everyDays, parseDaysString(STRING_EVERYDAY_1)), is(true));
        assertThat(isEquals(everyDays, parseDaysString(STRING_EVERYDAY_2)), is(true));
        assertThat(isEquals(everyDays, parseDaysString(STRING_EVERYDAY_3)), is(true));
        assertThat(isEquals(everyDays, parseDaysString(STRING_EVERYDAY_4)), is(true));
        assertThat(isEquals(everyDays, parseDaysString(STRING_EVERYDAY_5)), is(true));
        assertThat(isEquals(everyDays, parseDaysString(STRING_EVERYDAY_6)), is(true));
        assertThat(isEquals(everyDays, parseDaysString(STRING_EVERYDAY_7)), is(true));
        assertThat(isEquals(everyDays, parseDaysString(STRING_EVERYDAY_8)), is(true));
    }

    @Test
    public void shouldReturnWeekends() throws Exception {

        List<DayOfWeek> weekends = asList(WEEKENDS);

        assertThat(isEquals(weekends, parseDaysString(STRING_WEEKENDS_1)), is(true));
        assertThat(isEquals(weekends, parseDaysString(STRING_WEEKENDS_2)), is(true));
        assertThat(isEquals(weekends, parseDaysString(STRING_WEEKENDS_3)), is(true));
        assertThat(isEquals(weekends, parseDaysString(STRING_WEEKENDS_4)), is(true));
        assertThat(isEquals(weekends, parseDaysString(STRING_WEEKENDS_5)), is(true));
    }

    @Test
    public void shouldReturnWeekdays() throws Exception {

        List<DayOfWeek> weekdays = asList(WEEKDAYS);

        assertThat(isEquals(weekdays, parseDaysString(STRING_WEEKDAYS_1)), is(true));
        assertThat(isEquals(weekdays, parseDaysString(STRING_WEEKDAYS_2)), is(true));
        assertThat(isEquals(weekdays, parseDaysString(STRING_WEEKDAYS_3)), is(true));
        assertThat(isEquals(weekdays, parseDaysString(STRING_WEEKDAYS_4)), is(true));
    }

    @Test
    public void shouldReturnDays() throws Exception {

        assertThat(isEquals(asList(SUNDAY, MONDAY), parseDaysString(STRING_DAYS_1)), is(true));
        assertThat(isEquals(asList(WEEKDAYS, SUNDAY), parseDaysString(STRING_DAYS_2)), is(true));
        assertThat(isEquals(asList(WEEKENDS, MONDAY), parseDaysString(STRING_DAYS_3)), is(true));
        assertThat(isEquals(asList(WEEKENDS, MONDAY, THURSDAY), parseDaysString(STRING_DAYS_4)), is(true));
        assertThat(isEquals(asList(WEEKENDS, MONDAY), parseDaysString(STRING_DAYS_5)), is(true));
    }

    @Test
    public void shouldReturnEmptyList() throws Exception {
        assertThat(parseDaysString(INVALID_STRING).isEmpty(), is(true));
    }

    private boolean isEquals(Collection<?> baseList, Collection<?> resultList) {
        if (baseList.size() == resultList.size()) {
            List<Object> base = new ArrayList<Object>(baseList);
            for (Object d : resultList) {
                if (base.contains(d)) {
                    base.remove(d);
                } else {
                    return false;
                }
            }
        } else {
            return false;
        }

        return true;
    }
}
